# -*- coding: utf_8 -*-
# @Author : RSW
# @Time : 2022/1/8
# @Remark: pyweb
import json
import re
import time

from mxsoftpy import Server
# from mxsoftpy.exception import DBError, ParamsError
from db.common.IOTManager.Janitor.door import SelectDoorDB
from db.public.IOTManager.iot_base import IOTBaseDB
from index import _
# from model.common.SmartTool.TagManage.tag_group import TagGroupModel, TagModel
# from db.common.SmartTool.TagManage.tag_group import TagGroupDB, TagDB
from model.common.CRM.server_room import (GroupModel, GroupUpdateModel, SRoomModel, SRoomUpdateModel,
                                          )

from db.common.CRM.server_room import (GroupDB, SRoomDB, IOTRelevanceDB, RoomOverviewDB, IOTOperationDB,
                                       GroupOverviewDB)
from model.common.IOTManager.iot_base import SRoomIOTMiddleModel
from utils.classes.custom_exception import VerifyError
from utils.public.params_method import pagination, get_pagination_params, paging_data


class GroupServer(Server):
    __model__ = GroupModel
    __db__ = GroupDB

    def all_list(self):
        """展示机房与组"""
        return self.db.all_list()

    def all_search(self, **kwargs):
        """搜索机房与组"""
        search = ''
        if kwargs.get('search'):
            search = kwargs['search']

        return self.db.all_search(search)

    def list(self, **kwargs):
        """展示机房组(添加机房或机房组时使用)"""
        return self.db.list(**kwargs)

    def add(self, **kwargs):
        """
        添加机房组server层
        :param kwargs: 校验后的参数 dict
        :return:
        """
        add_data_dict = self.model(**kwargs).dict()  # 校验后的数据
        return self.db.add(**add_data_dict)

    def update(self, **kwargs):
        """
        修改机房组server层
        :param kwargs: 校验后的参数 dict
        :return:
        """

        """校验修改字段"""
        update_data_dict = GroupUpdateModel(**kwargs).dict(exclude_none=True)
        if update_data_dict:
            return self.db.update(kwargs['group_code'], **update_data_dict)
        return _('操作完成'), '没有要修改的属性'

    def delete(self, **kwargs):
        """
        删除机房组server层
        :param kwargs: 校验后的参数 dict
        :return:
        """
        return self.db.delete(kwargs['group_code'])

    def retrieve(self, **kwargs):
        """
        回显机房组server层
        :param kwargs: 校验后的参数 dict
        :return:
        """
        return self.db.retrieve(kwargs['group_code'])

    def route(self, **kwargs):
        """
        回显机房组路径server层
        :param kwargs: 校验后的参数 dict
        :return:
        """
        return self.db.route(kwargs['group_code'])


class SRoomServer(Server):
    __model__ = SRoomModel
    __db__ = SRoomDB

    def list(self, **kwargs):
        """
        机房详情页(点击组时显示)
        :param kwargs: 校验后的参数 dict
        :return:
        """

        """获取分页"""
        paging_dict = get_pagination_params(kwargs)
        paging_dict['page_size'] = paging_dict['page_size'] if paging_dict.get('page_size') else 20
        paging_dict['page_index'] = paging_dict['page_index'] if paging_dict.get('page_index') else 1
        if kwargs.get('group_search') and kwargs['group_search']:
            paging_dict = dict(paging_dict, **{'name__nclike': '*' + kwargs['group_search'] + '*'})

        """进行查询"""
        data_len, data_list = self.db.list(kwargs['group_parent'], **paging_dict)

        """增加分页"""
        res_dict = {"data": data_list, "total": data_len}

        data_dict = pagination(res_dict, paging_dict, data_len)
        return '操作完成', data_dict

    def add(self, **kwargs):
        """
        机房的添加
        :param kwargs: 校验后的参数 dict
        :return:
        """
        add_data_dict = self.model(**kwargs).dict()  # 校验后的数据
        return self.db.add(**add_data_dict)

    def update(self, **kwargs):
        """
        机房的修改
        :param kwargs: 校验后的参数 dict
        :return:
        """

        """校验修改字段"""
        update_data_dict = SRoomUpdateModel(**kwargs).dict(exclude_none=True)
        if update_data_dict:
            update_data_dict['update_time'] = int(time.time())
            return self.db.update(kwargs['sroom_code'], **update_data_dict)
        return _('操作完成'), '没有要修改的属性'

    def delete(self, **kwargs):
        """
        机房的删除
        :param kwargs:  校验后的参数 dict
        :return:
        """
        return self.db.delete(kwargs['sroom_code'])

    def retrieve(self, **kwargs):
        """
        机房的回显
        :param kwargs:  校验后的参数 dict
        :return:
        """
        return self.db.retrieve(kwargs['sroom_code'])

    def route(self, **kwargs):
        """
        回显机房组路径server层
        :param kwargs: 校验后的参数 dict
        :return:
        """
        return self.db.route(kwargs['sroom_code'])


class RoomOverviewServer(Server):
    """
    机房概览
    """
    __db__ = RoomOverviewDB
    __model__ = SRoomIOTMiddleModel

    def list(self, code):
        """

        :param code: 机房的code
        :return:
        """
        # 概览机柜容量

        # 查找所有动环的设备
        return self.db.overview(self.model(device_type="", iot_code="", sroom_code=code))


class GroutOverviewServer(Server):
    """
    机房组概览 机房清单
    """
    __db__ = GroupOverviewDB
    __model__ = SRoomIOTMiddleModel

    def list(self, **kwargs):
        """
        查找 概览信息
        :return:
        """

        search_state = [i for i in kwargs.get("state", "").split(";") if i]
        # 查找所有动环的设备
        total, room_list = self.db.list(parent=kwargs["group_parent"])
        res_list = []
        count = {"normal": 0, "environment": 0, "power_supply": 0, "security": 0}
        for room in room_list:

            state = self.db.overview(self.model(device_type="", iot_code="", sroom_code=room["code"]))
            room["state"] = state["state"]
            room["environment"] = state["environment"]["state"]
            room["power_supply"] = state["power_supply"]["state"]
            room["security"] = state["security"]["state"]
            self.statistics(state, count)

            if "0" in search_state and room["state"]:
                res_list.append(room)
            else:
                if "1" in search_state and room["environment"] == 2:
                    res_list.append(room)
                elif "2" in search_state and room["power_supply"] == 2:
                    res_list.append(room)
                elif "3" in search_state and room["security"] == 2:
                    res_list.append(room)
            # res_list.append(room)
        paging_data_dict = paging_data(res_list, **get_pagination_params(kwargs))

        res_dict = {"count": count, "data": paging_data_dict.pop("data")}
        res_dict.update(paging_data_dict)
        return res_dict

    @staticmethod
    def statistics(state, count):
        """
        统计
        @param state:
        @param count:
        @return:
        """
        if state["state"]:
            count["normal"] += 1
        if state["environment"]["state"] == 2:
            count["environment"] += 1
        if state["power_supply"]["state"] == 2:
            count["power_supply"] += 1
        if state["security"]["state"] == 2:
            count["security"] += 1


class IOTRelevanceServer(Server):
    """
    关联动环
    """
    __db__ = IOTRelevanceDB
    __model__ = SRoomIOTMiddleModel
    enter_key = "device_list"

    def update(self, code: str, **kwargs):
        # 判断机房是不是存在
        self.db.retrieve(code)

        device_list = self.verify_data(kwargs)

        for iot_device in device_list:
            self.db.create(self.model(device_type=iot_device["type"],
                                      iot_code=iot_device["code"],
                                      sroom_code=code))
        return True

    def verify_data(self, kwargs):
        """
        验证 设备是否存在 或者是否删除
        @param kwargs:
        @return:
        """
        device_list = self.data_decode(kwargs)
        # 验证参数
        for iot_device in device_list:
            try:
                self.iot_verify(iot_device)
            except (VerifyError, KeyError, TypeError):
                raise VerifyError(_("请检查设备参数%s" % iot_device))
            except TypeError:
                raise VerifyError(_("传入类型不正确"))
        return device_list

    def data_decode(self, kwargs):
        """
        解析入参
        @param kwargs:
        @return:
        """
        try:
            device_list = json.loads(kwargs[self.enter_key])
        except (json.JSONDecodeError, TypeError):
            device_list = kwargs[self.enter_key]
        return device_list

    def iot_verify(self, iot_device):
        """
        验证参数
        @return:
        """
        device_code = iot_device["code"]
        device_type = iot_device["type"]
        if device_type == "janitor":
            SelectDoorDB().retrieve(device_code)
        else:
            device_data = IOTBaseDB().retrieve(device_code)
            if not re.search(device_type, device_data["mxdevicetype"]):
                raise VerifyError


class IOTOperationServer(IOTRelevanceServer):
    __db__ = IOTOperationDB
    __model__ = SRoomIOTMiddleModel
    enter_key = "middle_code"

    def update(self, **kwargs):
        """
        更新关联动环的信息
        @param kwargs:
        @return:
        """
        operation_dict = {"update": self.db.update, "remove": self.db.delete}
        middle_list = self.verify_data(kwargs)

        operation_fun = operation_dict.get(kwargs["operation"])
        if operation_fun is None:
            raise VerifyError(_("operation 参数错误"))
        for middle_key in middle_list:
            operation_fun(**middle_key)
        return True

    def iot_verify(self, iot_device: dict):
        """验证参数"""
        if iot_device.get("code") is None:
            raise KeyError
        if iot_device.get("priority"):
            if not isinstance(iot_device["priority"], int):
                raise KeyError
